package com.shell.context.service.impl;

import com.shell.bee.base.utils.SpringContextUtil;
import com.shell.bee.base.utils.StringUtil;
import com.shell.bee.base.utils.SystemUtil;
import com.shell.bee.cache.Cache;
import com.shell.bee.cache.CacheBuilder;
import com.shell.bee.entity.auth.AuthOrgan;
import com.shell.bee.entity.auth.AuthUser;
import com.shell.context.service.ContextService;
import com.shell.context.utils.ConstantScanner;
import com.shell.customer.feign.CustomerFeign;
import com.shell.customer.po.CusGrp;
import com.shell.customer.po.CusRec;
import com.shell.feign.AuthFeign;
import com.shell.feign.PubApplicationFeign;
import com.shell.feign.PubDictionaryFeign;
import com.shell.framework.utils.ParameterHelper;
import com.shell.governor.modules.po.PubDictionary;
import com.shell.governor.modules.vo.ParameterVo;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service("contextService")
public class ContextServiceImpl implements ContextService {
	@Autowired
	private PubDictionaryFeign pubDictionaryFeign;
	@Autowired
	private PubApplicationFeign PubApplicationFeign;
	@Autowired
	private AuthFeign authFeign;
	@Autowired
	private CustomerFeign customerFeign;
	private static Cache<String, AuthUser> CACHE;

	public Map<String, Object> getConstantsData() throws Exception {
		Map<String, Object> contextMap = new HashMap();
		Map<String, Map<String, Map<String, String>>> constantsValueMap = new HashMap();
		Map<String, Map<String, Map<String, String>>> constantsNameValueMap = new HashMap();

		Map<String, Class> constants = ConstantScanner.scanConstants;
		Set<String> keys = constants.keySet();
		for (String key : keys) {
			Map<String, Map<String, String>> valueMap = SystemUtil.getConstantsValueMap((Class) constants.get(key));
			Map<String, Map<String, String>> nameValueMap = SystemUtil
					.getConstantsNameValueMap((Class) constants.get(key));
			constantsValueMap.put(key, valueMap);
			constantsNameValueMap.put(key, nameValueMap);
		}
		contextMap.put("constantsValueMap", constantsValueMap);
		contextMap.put("constantsNameValueMap", constantsNameValueMap);
		return contextMap;
	}

	public Map<String, Object> getDictionaryData() throws Exception {
		Map<String, Object> contextMap = new HashMap();

		List<PubDictionary> dics = this.pubDictionaryFeign.getAllDicTreeList();
		Map<String, Object> dicMap = new HashMap();
		for (PubDictionary pubDictionary : dics) {
			dicMap.put(pubDictionary.getDicCode(), pubDictionary);
		}
		contextMap.put("dictionaryMap", dicMap);
		return contextMap;
	}

	public Map<String, Object> getParameterData() throws Exception {
		Map<String, Object> contextMap = new HashMap();

		return contextMap;
	}

	public Map<String, Object> getApplicationsData() throws Exception {
		Map<String, Object> contextMap = new HashMap();

		contextMap.put("applications", this.PubApplicationFeign.getApplication());
		return contextMap;
	}

	public Map<String, Object> getSwitchs() {
		Map<String, Object> contextMap = new HashMap();
		Map<String, Object> switchMap = new HashMap();

		String esignSwitch = SpringContextUtil.getProperty("esign.switch");
		boolean esign = false;
		if ((StringUtil.notEmpty(esignSwitch)) && ("on".equals(esignSwitch))) {
			esign = true;
		}
		switchMap.put("esign", Boolean.valueOf(esign));

		String chainSwitch = SpringContextUtil.getProperty("chain.switch");
		boolean chain = false;
		if ((StringUtil.notEmpty(chainSwitch)) && ("on".equals(chainSwitch))) {
			chain = true;
		}
		switchMap.put("chain", Boolean.valueOf(chain));

		String cfcaSwitch = SpringContextUtil.getProperty("cfca.switch");
		boolean cfca = false;
		if ((StringUtil.notEmpty(cfcaSwitch)) && ("on".equals(cfcaSwitch))) {
			cfca = true;
		}
		switchMap.put("cfca", Boolean.valueOf(cfca));

		String ocrType = SpringContextUtil.getProperty("ocr.type");
		switchMap.put("ocrType", ocrType);

		contextMap.put("switchs", switchMap);
		return contextMap;
	}

	public String getCusState(String curEntId) {
		if (StringUtil.emptyAndNull(curEntId)) {
			return null;
		}
		CusRec cusRec = this.customerFeign.selectCusById(curEntId);
		if (cusRec == null) {
			return null;
		}
		return cusRec.getCusState();
	}

	public void setUserCache(String userId, String entId, String appCode, String terminalCode) {
		AuthUser user = this.authFeign.getLoggedUser(userId, entId, appCode, terminalCode);
		CusRec cusRec = this.customerFeign.selectCusById(entId);

		user.getExtension().put("group", getGroup(entId));
		if (cusRec != null) {
			user.getEnt().setCusType(cusRec.getCusType());
			user.getEnt().setGrpId(cusRec.getGrpId());
			user.getEnt().setOperator(this.customerFeign.findCusIsOperatorById(entId));
			user.getEnt().setArtisan(this.customerFeign.findCusIsArtisanById(entId));
		}
		String key = userId;
		if (StringUtil.notEmpty(entId)) {
			key = userId + "_" + entId;
		}
		if (StringUtil.notEmpty(terminalCode)) {
			key = key + "_" + terminalCode;
		}
		if (CACHE == null) {
			CACHE = CacheBuilder.newBuilder().build();
		}
		CACHE.put(key, user);
	}

	public AuthUser getUserCache(String userId, String entId, String appCode, String terminalCode) {
		String key = userId;
		if (StringUtil.notEmpty(entId)) {
			key = userId + "_" + entId;
		}
		if (StringUtil.notEmpty(terminalCode)) {
			key = key + "_" + terminalCode;
		}
		if (CACHE == null) {
			CACHE = CacheBuilder.newBuilder().build();
		}
		if (!CACHE.exists(key)) {
			setUserCache(userId, entId, appCode, terminalCode);
		}
		return (AuthUser) CACHE.get(key);
	}

	public Map<String, Object> getPlatformParams(String entId, String cusType) {
		return createResult(this.customerFeign.getRelCusIds(entId, cusType));
	}

	private Map<String, Object> createResult(Map<String, String> entIdMap) {
		Map<String, Object> result = new HashMap();

		String groupId = (String) entIdMap.get("gly_ent");

		String bizType = "3,4";
		commonMapMethod(bizType, result, groupId);

		return result;
	}

	private void commonMapMethod(String bizType, Map<String, Object> result, String groupId) {
		if (!StringUtil.emptyAndNull(groupId)) {
			List<ParameterVo> hxParam = ParameterHelper.getParameterList(bizType, groupId, "");
			for (ParameterVo parameterVo : hxParam) {
				if (!StringUtil.emptyAndNull(parameterVo.getParmValue())) {
					result.put(parameterVo.getParmCode(), parameterVo.getParmValue());
				}
			}
		}
	}

	private Map<String, Object> getGroup(String entId) {
		List<CusGrp> adminGroups = this.customerFeign.findCusGroup(entId, "GROUP_ADMIN");
		List<CusGrp> firstTrialGroups = this.customerFeign.findCusGroup(entId, "GROUP_FIRST_TRIAL");
		List<CusGrp> lastTrialGroups = this.customerFeign.findCusGroup(entId, "GROUP_LAST_TRIAL");
		List<Map<String, String>> adminGroupsM = new ArrayList();
		for (Iterator localIterator = adminGroups.iterator(); localIterator.hasNext();) {
			CusGrp grp = (CusGrp) localIterator.next();
			if (grp != null) {
				Map<String, String> m = new HashMap();
				m.put("grpId", grp.getGrpId());
				m.put("grpName", grp.getGrpName());
				adminGroupsM.add(m);
			}
		}
		Object firstTrialGroupsM = new ArrayList();
		for (Iterator localIterator = firstTrialGroups.iterator(); localIterator.hasNext();) {
			CusGrp grp = (CusGrp) localIterator.next();
			if (grp != null) {
				Map<String, String> m = new HashMap();
				m.put("grpId", grp.getGrpId());
				m.put("grpName", grp.getGrpName());
				((List) firstTrialGroupsM).add(m);
			}
		}
		
		List<Map<String, String>> lastTrialGroupsM = new ArrayList();
		for (CusGrp grp : lastTrialGroups) {
			if (grp != null) {
				Map<String, String> m = new HashMap();
				m.put("grpId", grp.getGrpId());
				m.put("grpName", grp.getGrpName());
				lastTrialGroupsM.add(m);
			}
		}
		Map<String, Object> m = new HashMap();
		m.put("adminGroups", adminGroupsM);
		m.put("firstTrialGroups", firstTrialGroupsM);
		m.put("lastTrialGroups", lastTrialGroupsM);
		return m;
	}
}
